0402. 移掉 K 位数字【中等】
1. 📝 题目描述
给你一个以字符串表示的非负整数 num 和一个整数 k,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
示例 1 :
txt
输入:num = "1432219", k = 3
输出:"1219"
解释:移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。1
2
3
2
3
示例 2 :
txt
输入:num = "10200", k = 1
输出:"200"
解释:移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。1
2
3
2
3
示例 3 :
txt
输入:num = "10", k = 2
输出:"0"
解释:从原数字移除所有的数字,剩余为空就是 0。1
2
3
2
3
提示:
1 <= k <= num.length <= 10^5num仅由若干位数字(0 - 9)组成- 除了 0 本身之外,
num不含任何前导零
2. 🎯 s.1 - 单调栈 + 贪心
c
char* removeKdigits(char* num, int k) {
int len = strlen(num);
char* stack = (char*)malloc(len + 1);
int top = 0;
for (int i = 0; i < len; i++) {
while (k > 0 && top > 0 && stack[top - 1] > num[i]) { top--; k--; }
stack[top++] = num[i];
}
top -= k;
// 去前导零
int start = 0;
while (start < top - 1 && stack[start] == '0') start++;
stack[top] = '\0';
char* res = (char*)malloc(top - start + 1);
strcpy(res, stack + start);
free(stack);
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
js
/**
* @param {string} num
* @param {number} k
* @return {string}
*/
var removeKdigits = function (num, k) {
const stack = []
for (const ch of num) {
while (k > 0 && stack.length > 0 && stack[stack.length - 1] > ch) {
stack.pop()
k--
}
stack.push(ch)
}
while (k > 0) {
stack.pop()
k--
}
const res = stack.join('').replace(/^0+/, '')
return res || '0'
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
py
class Solution:
def removeKdigits(self, num: str, k: int) -> str:
stack = []
for ch in num:
while k and stack and stack[-1] > ch:
stack.pop()
k -= 1
stack.append(ch)
stack = stack[:-k] if k else stack
return ''.join(stack).lstrip('0') or '0'1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 时间复杂度:
,其中 是数字字符串长度 - 空间复杂度:
算法思路:
- 维护单调递增栈,当前数字比栈顶小时弹出栈顶(贪心地移除较大数字)
- 最多弹出
次,最后去除前导零